#include <cstdio>
#include <cstring>

const int N = 50005;
int n, m;
unsigned int ans[6][6], tmp[6][6];
char s[N];

struct Node {
  unsigned int f[6][6];
  char tag;
} tr[N << 2];

inline void merge(unsigned int a[6][6], unsigned int b[6][6], unsigned int c[6][6]) {
  for (int i = 1; i <= 5; ++i)
    for (int j = 1; j <= 5; ++j) {
      c[i][j] = a[i][j] + b[i][j];
      for (int k = i; k < j; ++k) {
        c[i][j] += a[i][k] * b[k + 1][j];
      }
    }
}

inline void pushup(int x) { merge(tr[x << 1].f, tr[x << 1 | 1].f, tr[x].f); }

inline void pushdown(int x, int l, int r) {
  static int ls, rs, mid;
  if (tr[x].tag) {
    ls = x << 1, rs = x << 1 | 1, mid = (l + r) >> 1;
    tr[ls].tag = tr[rs].tag = tr[x].tag;
    memset(tr[ls].f, 0, sizeof(tr[ls].f));
    memset(tr[rs].f, 0, sizeof(tr[rs].f));
    switch (tr[x].tag) {
      case '(':
        tr[ls].f[1][1] = mid - l + 1, tr[rs].f[1][1] = r - mid;
        break;
      case '0':
        tr[ls].f[2][2] = tr[ls].f[4][4] = mid - l + 1, tr[rs].f[2][2] = tr[rs].f[4][4] = r - mid;
        break;
      case 'w':
        tr[ls].f[3][3] = mid - l + 1, tr[rs].f[3][3] = r - mid;
        break;
      case ')':
        tr[ls].f[5][5] = mid - l + 1, tr[rs].f[5][5] = r - mid;
    }
    tr[x].tag = 0;
  }
}

void build(int x, int l, int r) {
  if (l == r) {
    if (s[l] == '(')
      tr[x].f[1][1] = 1;
    else if (s[l] == '0')
      tr[x].f[2][2] = tr[x].f[4][4] = 1;
    else if (s[l] == 'w')
      tr[x].f[3][3] = 1;
    else if (s[l] == ')')
      tr[x].f[5][5] = 1;
    return;
  }
  int mid = (l + r) >> 1;
  build(x << 1, l, mid);
  build(x << 1 | 1, mid + 1, r);
  pushup(x);
}

void query(int x, int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    merge(tmp, tr[x].f, ans);
    memcpy(tmp, ans, sizeof(tmp));
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(x, l, r);
  if (L <= mid) query(x << 1, l, mid, L, R);
  if (mid < R) query(x << 1 | 1, mid + 1, r, L, R);
}

void modify(int x, int l, int r, int L, int R, char ch) {
  if (L <= l && r <= R) {
    tr[x].tag = ch;
    memset(tr[x].f, 0, sizeof(tr[x].f));
    switch (ch) {
      case '(':
        tr[x].f[1][1] = r - l + 1;
        break;
      case '0':
        tr[x].f[2][2] = tr[x].f[4][4] = r - l + 1;
        break;
      case 'w':
        tr[x].f[3][3] = r - l + 1;
        break;
      case ')':
        tr[x].f[5][5] = r - l + 1;
    }
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(x, l, r);
  if (L <= mid) modify(x << 1, l, mid, L, R, ch);
  if (mid < R) modify(x << 1 | 1, mid + 1, r, L, R, ch);
  pushup(x);
}

int main() {
  scanf("%d%d", &n, &m);
  scanf("%s", s + 1);
  int x, y;
  char ch[2], opt[2];
  build(1, 1, n);
  while (m--) {
    scanf("%s", opt);
    switch (opt[0]) {
      case 'A':
        scanf("%d%s", &x, ch);
        modify(1, 1, n, x, x, ch[0]);
        break;
      case 'B':
        scanf("%d%d%s", &x, &y, ch);
        modify(1, 1, n, x, y, ch[0]);
        break;
      case 'C':
        scanf("%d%d", &x, &y);
        memset(tmp, 0, sizeof(tmp));
        query(1, 1, n, x, y);
        printf("%u\n", ans[1][5]);
    }
  }
  return 0;
}